#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2021/5/16 17:18
# @Author  : LiShan
# @Email   : lishan_1997@126.com
# @File    : compar_delay.py
# @Note    : this is note
import sys

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

font = {'family' : 'SimSun',
    'weight' : 'bold',
    'size'  : '16'}
plt.rc('font', **font)
plt.rc('axes',unicode_minus=False)
# plt.rcParams['figure.facecolor'] = "#FFFFF0"  # 设置窗体颜色
# plt.rcParams['axes.facecolor'] = "#FFFFF0"  # 设置绘图区颜色

path = sys.path[0].replace("\\", "/")

dqn_record_file = path + "/model/txt/test_drl_record.txt"
fix_record_file = path + "/fix/txt/test_fix_record.txt"
compar_file = path + "/fix/txt/compar.txt"
compar_img = path + "/fix/png/compare_delay.png"
compar_avg_img = path + "/fix/png/compare_avg_delay.png"
compar_avg_3d_img = path + "/fix/png/compare_avg_delay_3d.png"
plan_img = path + "/fix/png/dqn_plan.png"
plan_freq_img = path + "/fix/png/dqn_plan_freq.png"
delay_hist_img = path + "/fix/png/delay_hist.png"
delay_freq_img = path + "/fix/png/delay_freq.png"
delay_box_img = path + "/fix/png/delay_box.png"
dqn_dealy_img = path + "/fix/png/plot_dqn_delay.png"


if __name__ == '__main__':
    # dqn 延误
    names = ["step", "plan", "delay", "reward"]
    data = pd.read_csv(dqn_record_file, sep="\t+", names=names, engine="python")
    dqn_delay = list(data["delay"].values)
    dqn_plan = list(data["plan"].values)
    mean_delay = round(sum(dqn_delay) / len(dqn_delay), 3)

    # 绘图
    x = np.linspace(0, len(dqn_delay) - 1, len(dqn_delay))
    plt.plot(x, dqn_delay, color='black', marker='D', linestyle='-', linewidth='1.0')
    plt.plot(x, [mean_delay for i in range(len(x))], color='gray', linestyle='--')
    # 设置坐标轴名称
    plt.xlabel("信号周期", fontproperties="SimSun", size=10.5)
    plt.ylabel("平均延误时间(s)", fontproperties="SimSun", size=10.5)
    # 设置图例
    legend = ["delay"]
    plt.legend(legend, loc="best", frameon=False)
    # 保存图片
    plt.savefig(dqn_dealy_img, dpi=600)
    # 关闭绘图
    plt.close()

    # fix 延误
    names = ["plan", "step", "delay"]
    data = pd.read_csv(fix_record_file, sep="\s+", names=names)
    data.sort_values(by='delay', inplace=True)
    fix_plan = list(data["plan"].values)
    plan_num = len(fix_plan)
    fix_delay = list(data["delay"].values)

    # 延误对比
    compar = list(map(lambda x: round((x - mean_delay) / x * 100, 2), fix_delay))
    content = ""
    content += "dqn平均延误：{}".format(mean_delay)
    content += "\n"
    content += "min-fix平均延误：{}".format(min(fix_delay))
    content += "\n"

    for num in range(int(plan_num / 10) + min(1, plan_num % 10)):
        content += "*"*120
        content += "\n"
        content += "方案 "+"%10d " * 10 % tuple(fix_plan[num * 10 + i] for i in range(0, 10))
        content += "\n"
        content += "延误 "+"%10.3f "* 10 % tuple(fix_delay[num * 10 + i] for i in range(0, 10))
        content += "\n"
        content += "降低 "+"%9.2f%% " * 10 % tuple(compar[num * 10 + i] for i in range(0, 10))
        content += "\n"
        content += "*" * 120
        content += "\n"

    with open(compar_file, 'w') as f:
        f.write(content)
    print(content)

    # 绘图
    names = ["plan", "step", "delay"]
    data = pd.read_csv(fix_record_file, sep="\s+", names=names)
    fix_plan = list(data["plan"].values)
    plan_num = len(fix_plan)
    fix_delay = list(data["delay"].values)
    min_delay = min(filter(lambda x: x > 0, fix_delay))
    fix_min_idx = fix_plan[fix_delay.index(min_delay)]
    fix_max_idx = fix_plan[fix_delay.index(max(fix_delay))]
    compar = list(map(lambda x: round((x - mean_delay) / x * 100, 2), fix_delay))
    x = np.linspace(0, len(compar) - 1, len(compar))
    plt.plot(x, fix_delay, color='black', marker='D', linestyle='-')
    plt.plot(x, [mean_delay for i in range(len(fix_plan))] , color='gray', marker='*', linestyle='--')
    for i in range(len(x)):
        plt.text(i, fix_delay[i] + 0.2, str(round(compar[i], 2)) + '%', ha='center',
                 fontproperties="Times New Roman", size=5.5)
    # 设置坐标轴名称
    plt.xlabel("配时方案", fontproperties="SimSun", size=10.5)
    plt.ylabel("延误对比", fontproperties="SimSun", size=10.5)
    # 设置图例
    legend = ["Fix Dalay", "DQN Dalay"]
    plt.legend(legend, loc="best", frameon=False)
    # 保存图片
    plt.savefig(compar_avg_img, dpi=600)
    # 关闭绘图
    plt.close()

    # min-fix 延误
    min_fix_file = fix_record_file[:-4] + '_' + str(fix_min_idx) + '.txt'
    print("读取文件：", min_fix_file)
    names = ["step", "delay"]
    data = pd.read_csv(min_fix_file, sep="\t+", names=names, engine="python")
    fix_min_delay = list(data["delay"].values)

    # max-fix 延误
    max_fix_file = fix_record_file[:-4] + '_' + str(fix_max_idx) + '.txt'
    print("读取文件：", max_fix_file)
    names = ["step", "delay"]
    data = pd.read_csv(max_fix_file, sep="\t+", names=names, engine="python")
    fix_max_delay = list(data["delay"].values)

    """dqn、min-fix、max-fix测试延误图"""
    # 绘图
    fix_max_mean_delay = round(sum(fix_max_delay) / len(fix_max_delay), 3)
    fix_min_mean_delay = round(sum(fix_min_delay) / len(fix_min_delay), 3)
    dqn_mean_delay = round(sum(dqn_delay) / len(dqn_delay), 3)
    x = np.linspace(0, len(dqn_delay) - 1, len(dqn_delay))
    plt.plot(x, fix_max_delay, color='gray', marker='*', linestyle=':')
    plt.plot(x, fix_min_delay, color='gray', marker='o', linestyle=':')
    plt.plot(x, dqn_delay, color='black', marker='D', linestyle='--')
    plt.plot(x, [fix_max_mean_delay for i in range(len(fix_max_delay))], color='gray', marker='*', linewidth=0.5, linestyle='--')
    plt.plot(x, [fix_min_mean_delay for i in range(len(fix_min_delay))], color='gray', marker='o', linewidth=0.5, linestyle='--')
    plt.plot(x, [dqn_mean_delay for i in range(len(dqn_delay))], color='black', marker='D', linewidth=0.5, linestyle='--')
    # 设置坐标轴名称
    plt.xlabel("信号周期", fontproperties="SimSun", size=10.5)
    plt.ylabel("延误时间(s)", fontproperties="SimSun", size=10.5)
    # 设置图例
    legend = ["Fix Max Dalay", "Fix Min Dalay", "DQN Dalay"]
    plt.legend(legend, loc="best", frameon=False)
    # 保存图片
    plt.savefig(compar_img, dpi=600)
    # 关闭绘图
    plt.close()

    """dqn、fix-min、fix-max方案延误3D图"""
    # dqn 延误
    names = ["step", "plan", "delay", "reward"]
    data = pd.read_csv(dqn_record_file, sep="\t+", names=names, engine="python")
    dqn_step = list(data["step"].values)
    dqn_delay = list(data["delay"].values)
    dqn_plan = list(data["plan"].values)
    mean_delay = round(sum(dqn_delay) / len(dqn_delay), 3)

    # fix 延误
    names = ["plan", "step", "delay"]
    data = pd.read_csv(fix_record_file, sep="\s+", names=names)
    data.sort_values(by='delay', inplace=True)
    fix_plan = list(data["plan"].values)
    plan_num = len(fix_plan)
    fix_delay = list(data["delay"].values)
    min_delay = min(filter(lambda x: x > 0, fix_delay))
    fix_min_idx = fix_plan[fix_delay.index(min_delay)]
    fix_max_idx = fix_plan[fix_delay.index(max(fix_delay))]

    # min-fix 延误
    min_fix_file = fix_record_file[:-4] + '_' + str(fix_min_idx) + '.txt'
    print("读取文件：", min_fix_file)
    names = ["step", "delay"]
    data = pd.read_csv(min_fix_file, sep="\t+", names=names, engine="python")
    fix_min_step = list(data["step"].values)
    fix_min_plan = [fix_min_idx for _ in range(len(fix_min_step))]
    fix_min_delay = list(data["delay"].values)

    # max-fix 延误
    max_fix_file = fix_record_file[:-4] + '_' + str(fix_max_idx) + '.txt'
    print("读取文件：", max_fix_file)
    names = ["step", "delay"]
    data = pd.read_csv(max_fix_file, sep="\t+", names=names, engine="python")
    fix_max_step = list(data["step"].values)
    fix_max_plan = [fix_max_idx for _ in range(len(fix_max_step))]
    fix_max_delay = list(data["delay"].values)

    # 绘图
    fig = plt.figure()
    ax = fig.add_subplot(projection='3d')
    ax.scatter(fix_max_plan, fix_max_step, fix_max_delay, color='gray', marker='*')
    ax.scatter(fix_min_plan, fix_min_step, fix_min_delay, color='gray', marker='o')
    ax.scatter(dqn_plan, dqn_step, dqn_delay, color='black', marker='^')
    plt.tick_params(labelsize=8.5)
    labels = ax.get_xticklabels() + ax.get_yticklabels() + ax.get_zticklabels()
    [label.set_fontname('Times New Roman') for label in labels]
    ax.set_ylabel("Step", fontproperties="Times New Roman", size=8.5)
    ax.set_xlabel("Plan", fontproperties="Times New Roman", size=8.5)
    ax.set_zlabel("Delay", fontproperties="Times New Roman", size=8.5)
    # 去除边框
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)
    ax.spines['bottom'].set_visible(False)
    ax.spines['left'].set_visible(False)
    # 设置图例
    legend = ["Fix Max Dalay", "Fix Min Dalay", "DQN Dalay"]
    box = ax.get_position()
    ax.set_position([box.x0, box.y0, box.width * 0.9, box.height])
    font = {'family': 'Times New Roman', 'weight': 'normal', 'size': 8.5}
    # bbox_to_anchor,第一个数控制左右移动，第二个数控制上下移动
    ax.legend(legend, bbox_to_anchor=(1.05, 0.65), loc=3, ncol=1, columnspacing=0.3,
              labelspacing=0.3, prop=font, frameon=False)
    ax.view_init(elev=10, azim=-30)
    plt.savefig(compar_avg_3d_img, dpi=600)
    plt.close()

    """dqn方案散点图"""
    # 绘图
    x = np.linspace(0, len(dqn_plan) - 1, len(dqn_plan))
    plt.scatter(x, dqn_plan, color='black', s=20, marker='o')
    # 设置坐标轴名称
    plt.xlabel("信号周期", fontproperties="SimSun", size=10.5)
    plt.ylabel("配时方案", fontproperties="SimSun", size=10.5)
    # 保存图片
    plt.savefig(plan_img, dpi=600)
    # 关闭绘图
    plt.close()

    """dqn方案频率直方图"""
    se = pd.Series(dqn_plan)
    countDict = dict(se.value_counts())
    proportitionDict = dict(se.value_counts(normalize=True))
    plan_freq = []
    for i in range(plan_num):
        try:
            plan_freq.append(proportitionDict[i])
        except:
            plan_freq.append(0)
    print("dqn中各方案选择频率", plan_freq)

    # 绘图
    x = np.linspace(0, len(plan_freq) - 1, len(plan_freq))
    plt.bar(x, plan_freq, 0.5, color="gray", edgecolor="k")
    # 设置坐标轴名称
    plt.xlabel("配时方案", fontproperties="SimSun", size=10.5)
    plt.ylabel("出现频率", fontproperties="SimSun", size=10.5)
    # 保存图片
    plt.savefig(plan_freq_img, dpi=600)
    # 关闭绘图
    plt.close()

    """dqn延误频率直方图(彩图)"""
    # 绘图
    data = [fix_max_delay, fix_min_delay, dqn_delay]
    n, bins, patches = plt.hist(data, bins=10, rwidth=0.8, align='left', color=['r', 'g', 'b'], edgecolor='k')
    # 设置坐标轴名称
    plt.xlabel("延误时间", fontproperties="SimSun", size=10.5)
    plt.ylabel("出现频率", fontproperties="SimSun", size=10.5)
    # 保存图片
    plt.savefig(delay_hist_img, dpi=600)
    # 关闭绘图
    plt.close()

    """dqn延误频率直方图(黑白)"""
    # 绘图
    data = [fix_max_delay, fix_min_delay, dqn_delay]
    n, bins, _ = plt.hist(data, bins=10)
    y = np.array(n) / np.array(sum(n[0]))
    bins = np.array(bins)
    plt.close()
    x = []
    for i in range(len(bins) - 1):
        x.append((bins[i] + bins[i+1])/2)
    m = np.array(x)
    w = 1.5
    hatch = ['', '///', '...']
    for i in range(len(y)):
        rects = plt.bar(m + w * i, y[i], width=w, color='w', edgecolor='k', hatch=hatch[i])
    # 设置坐标轴名称
    plt.xlabel("延误时间", fontproperties="SimSun", size=10.5)
    plt.ylabel("出现频率", fontproperties="SimSun", size=10.5)
    # 设置图例
    legend = ["Fix Max Dalay", "Fix Min Dalay", "DQN Dalay"]
    plt.legend(legend, loc="best", frameon=False)
    # 保存图片
    plt.savefig(delay_freq_img, dpi=600)
    # 关闭绘图
    plt.close()

    """dqn、fix-min、random、fix-max延误箱型图"""
    plt.figure(figsize=(10, 5))  # 设置画布的尺寸
    labels = 'fix-max', 'fix-min', 'dqn'  # 图例
    boxprops = dict(linestyle='--', linewidth=3, color='darkgoldenrod')
    flierprops = dict(marker='o', markerfacecolor='green', markersize=12,
                      linestyle='none')
    medianprops = dict(linestyle='-', linewidth=2.5, color='black')
    meanpointprops = dict(marker='D', markeredgecolor='black',
                          markerfacecolor='gray')
    meanlineprops = dict(linestyle='--', linewidth=2.5, color='purple')
    data = [fix_max_delay, fix_min_delay, dqn_delay]
    # vert=False:水平箱线图；showmeans=True：显示均值
    plt.boxplot(data, labels=labels, vert=False, showmeans=True, medianprops=medianprops, meanprops=meanpointprops)
    for i in range(len(data)):
        mean = np.mean(data[i])
        plt.text(mean, i + 1.2, str(round(float(mean), 3)), ha='center', fontproperties="Times New Roman", size=10.5)
    # 设置坐标轴名称
    plt.xlabel("延误时间(s)", fontproperties="SimSun", size=10.5)
    plt.ylabel("配时算法", fontproperties="SimSun", size=10.5)
    # 保存图片
    plt.savefig(delay_box_img, dpi=600)
    # 关闭绘图
    plt.close()

    print("绘图完成...")
